5. Docker网络配置
当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker 同样有着很多不完善的地方,网络方面就是 Docker 比较薄弱的部分。因此,我们有必要深入了解 Docker 的网络知识,以满足更高的网络需求。
网络类型
默认网络
安装 Docker 以后,会默认创建三种网络,可以通过docker network ls
查看。在学习 Docker 网络之前,我们有必要先来了解一下这几种网络都是什么意思。
1 | [root@localhost ~]# docker network ls |
bridge:为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,默认为该模式
在该模式中,Docker 守护进程创建了一个虚拟以太网桥docker0 ,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。
默认情况下,守护进程会创建一对对等虚拟设备接口veth pair ,将其中一个接口设置为容器的eth0接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似vethxxx 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。
Docker 桥接网络架构 Docker 容器网卡配置 Docker 外接网卡 通过以上的比较可以发现,证实了之前所说的:守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的eth0接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似vethxxx 这样的名字命名。同时,守护进程还会从网桥docker0 的私有地址空间中分配一个IP地址和子网给该容器,并设置docker0的IP地址为容器的默认网关。也可以安装
yum install -y bridge-utils
以后,通过brctl show
命令查看网桥信息。通过
docker network inspect bridge
查看所有bridge网络模式下的容器,在Container节点中可以看到容器名称。关于bridge网络模式的使用,只需要在创建容器时通过参数–net bridge或者–network bridge指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。
host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
- 采用host网络模式的Docker Container,可以直接使用宿主机的IP地址与外界进行通信,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP。容器内服务的端口也可以使用宿主机的端口,无需进行NAT转换。
- host网络模式可以让容器共享宿主机网络栈,好处是外部主机与主机直接通信,但是容器的网络缺少隔离。
- host网络模式需要在创建容器时通过参数 –net host 或者 –network host指定;
1 | $ docker run -id --name python01 --network host mypython3 |
- none:容器有独立的network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等。
- container:新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定容器共享IP、端口范围等。
- 处于这个模式下的Docker容器会共享一个网络栈,简单来讲就是两个容器共用一张网卡,这样两个容器之间可以使用localhost高效快速通信。
- container网络模式是Docker中一种较为特别的网络模式。在创建容器时通过参数 –net container:已运行的容器名称|ID 或者 –network container:已运行的容器名称|ID指定。
1 | $ docker run -id --name python01 --net bridge mypython3 |
自定义网络
虽然 Docker 提供的默认网络使用比较简单,但是为了保证各容器中应用的安全性,在实际开发中更推荐使用自定义的网络进行容器管理,以及启用容器名称到 IP 地址的自动 DNS 解析。注意在 bridge 的网卡模式下,IP 不固定!关闭容器 IP 地址就会被释放,启动的时候再获取 IP。
从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称进行通信。方法很简单,只要在创建容器时使用–name 为容器命名即可。但是使用 Docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。
1 | # 查看network帮助信息 |